home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gigarom 1
/
Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso
/
FILES
/
DEV
/
I-Z
/
Xlisp_Source.cpt
/
Step10.LSP
< prev
next >
Wrap
Lisp/Scheme
|
1985-04-27
|
9KB
|
247 lines
;+
; STEP 1.0 : (C) Copyright 1985 by Gregory Frascadore
;
; This software may be copied, distributed to others, and modified as long
; as it is not sold for profit, and as long as this copyright notice is
; retained intact. For further information regarding STEP, contact the
; author at:
; frascado%umn-cs.CSNET (on CSNET)
; 75106,662 (on CompuServe)
;-
;+
; STEP 1.0
; DESCRIPTION
; STEP is an interactive debugging tool for use with XLISP 1.4 . With
; modification, STEP may work with later versions of XLISP or with other
; lisp systems.
;
; UPDATE HISTORY
; Version 1.0 - Original version, March 1985 by Gregory Frascadore.
;
;-
;+
; Here is where the global symbols are given values. Global symbols are
; distinguished from other symbols by their starting and ending asterisks.
; ie *global* . Function parameters start with an asterisk, but do not end
; with one ie *foo. Local symbols (like those in do, and let) end in asterisks
; ie bar*
;-
(setq *step-inprompt* '? ; Each instep is identified by leading '?'
*step-outprompt* '= ; Outsteps have leading '='
*step-count* 0 ; How many steps to make without prompting.
*step-indent* 0 ; The initial amount of indentation.
*step-indent-incr* 2 ; How much more to indent at each new level
*step-keys* nil ; List of breakpoint atoms
*step-transparent* t ; Flag, determines when to print to user.
*evalhookfnc* '(lambda (*sexpr) (eval *sexpr)) )
; The initial evalhook is a nop function.
;+
; step
; Turns on stepping or sets breakpoints.
;
; format
; (step [<atom>]...) -if no atoms are specified, stepping begin immediately.
;-
(defun step (&rest *keys)
(if *keys
(setq *step-keys* *keys
*step-transparent* t )
(setq *step-transparent* nil) )
(setq *step-count* 0
*step-indent* 0 )
(rplacd *evalhookfnc* (cdr stepper)) ; Set stepper as evalhookfnc
(setq *evalhook* *evalhookfnc*) t) ; then start intercepting evals.
;+
; nostep
; Turns off stepping.
;
; format
; (nostep)
; returns t always
;-
(defun nostep ()
(rplacd *evalhookfnc* '((*sexpr) (eval *sexpr))) t)
(defun stepper (*sexpr)
; If the car of the expression being evaluated is in the breakpoint list
; then take the stepper out of transparent mode.
(if (and (consp *sexpr)
(member (car *sexpr) *step-keys*) )
(setq *step-transparent* nil))
; Start indenting at a deeper level. If the indent is in some weird state
; restore it to a level 1 indent ie 0 + incr.
(if (<= *step-indent* 0)
(setq *step-indent* *step-indent-incr*)
(setq *step-indent* (+ *step-indent-incr* *step-indent*)) )
; Eval the current *sexpr. If we are at level 1, set a catch we can throw
; to from deeper levels. Otherwise just do a simple step-evel. When completing
; a level 1 eval, turn off transparency and restore the evalhookfnc if they
; were disabled from a deeper level.
(prog1
(cond ((eql *step-indent* *step-indent-incr*)
(prog1
(catch '*step-toplevel* (step-eval *sexpr))
(setq *step-count* 0)
(cond ((eql *step-transparent* 'c)
(setq *step-transparent* nil)
(rplacd *evalhookfnc* (cdr stepper)) ) ) ) )
(t (step-eval *sexpr)) )
(setq *step-indent* (- *step-indent* *step-indent-incr*)) ) )
(defun step-eval (*sexpr)
; Eval the current *sexpr. If *step-count* is greater than 0, do not prompt
; the user for instructions, but do continue to produce output if not in
; transparent mode.
(cond ((zerop *step-count*)
(if (not *step-transparent*)
(prog2
(step-prompt *step-inprompt* *sexpr)
(step-prompt *step-outprompt* (step-docmd *sexpr))
(terpri) )
(evalhook *sexpr stepper nil) ) )
((> *step-count* 0)
(setq *step-count* (1- *step-count*))
(if (not *step-transparent*)
(prog2
(progn
(step-prompt *step-inprompt* *sexpr)(terpri))
(step-prompt *step-outprompt*
(evalhook *sexpr stepper nil))(terpri) )
(evalhook *sexpr stepper nil) ) )
(t (break "%Error, Stepper loses")) ) )
(defun step-docmd (*sexpr)
; If the *sexpr is an atom, don't bother asking the user what to do. Just echo
; the atom and its value. If its not an atom, ask the user what to do until
; he gives you a legal responce that either continues or aborts the evaluation.
(do* (cmd* (value* (cond ((atom *sexpr) (terpri) (eval *sexpr))
(t '*unbound*) )))
((cond ((boundp 'value*) t)
(t (setq cmd* (step-getcmd)) nil) )
value*)
(case cmd*
'(? (step-help))
'(+ (let ((key* (read)))
(if (atom key*)
(setq *step-keys*
(cons key* *step-keys*) )
(step-huh?) ) ))
'(- (let ((key* (read)))
(if (atom key*)
(setq *step-keys*
(remove key* *step-keys*) )
(step-huh?) ) ))
'(b (break "STEP BREAK, type 'continue' or 'quit' when done"))
'(c (setq *step-transparent* 'c)
(setq value* (evalhook *sexpr stepper nil)) )
'(e (throw '*step-toplevel* t))
'(g (rplacd *evalhookfnc* '((*sexpr) (eval *sexpr)))
(setq *step-transparent* 'c)
(setq value* (eval *sexpr)) )
'(h (step-help))
'(n (setq value* (eval *sexpr)))
'(q (setq *step-keys* nil)
(rplacd *evalhookfnc* '((*sexpr) (eval *sexpr)))
(throw '*step-toplevel* t) )
'(s (setq value* (evalhook *sexpr stepper nil)))
'(x (throw '*step-toplevel* t) )
'(t (cond ((numberp cmd*)
(setq *step-count* cmd*)
(setq value* (evalhook *sexpr stepper nil)) )
(t (step-huh?)) ) ) ) ) )
(defun step-getcmd ()
; Since XLISP normally prompts '>' when asking for input, we add another
; '>' here to distinguish a stepper prompt. ie stepper prompts >>
(princ " >")
(read))
(defun step-prompt (*prompt *sexpr)
; Here we print the *sexpr with a informative leading character (usually
; either ? or = ). If the *sexpr is long then we won't print the whole thing
; just an outline which abbreviates nested lists as (...)
(spaces *step-indent*)
(princ *prompt)
(let ((len (flatc *sexpr)))
(cond ((<= (- len *step-indent*) 75)
(princ *sexpr) )
(t (short-princ *sexpr)) ) )
*sexpr )
(defun step-help ()
(princ "Here is a summary of the available commands:\n")
(princ " s - steps once more\n")
(princ " ? - prints this help\n")
(princ " b - enter a break loop\n")
(princ " c - continue program until next breakpoint\n")
(princ " e - exit program, return to toplevel\n")
(princ " g - go on without further stepping interruptions\n")
(princ " h - prints this help\n")
(princ " n - continue stepping, but no deeper\n")
(princ " q - quit program, clear breakpoints, return to toplevel\n")
(princ " x - exit, same as e\n")
(princ " # - make # steps at once\n")
(princ " + <atom> - add this atom to list of breakpoints\n")
(princ " - <atom> - remove this atom from list of breakpoints\n" ) )
(defun step-huh? ()
(princ "Huh? Type h or ? for help ") )
;+
; The End.
;-